package com.main.usermanagement.domain.user.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.main.common.base.base.BaseAssemblerFactory;
import com.main.common.base.resp.RespBody;
import com.main.usermanagement.application.event.publish.AddAccountEventPublisher;
import com.main.usermanagement.application.service.RegisterService;
import com.main.usermanagement.domain.user.aggregate.User;
import com.main.usermanagement.domain.user.entity.UserAddress;
import com.main.usermanagement.domain.user.entity.UserInfo;
import com.main.usermanagement.domain.user.repository.UserAddressRepository;
import com.main.usermanagement.domain.user.repository.UserInfoRepository;
import com.main.usermanagement.domain.user.repository.UserRepository;
import com.main.usermanagement.interfaces.assembler.RegisterAssembler;
import com.main.usermanagement.interfaces.dto.RegisterDTO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class RegisterServiceImpl implements RegisterService {

    @Resource
    private UserRepository userRepository;
    @Resource
    private UserInfoRepository userInfoRepository;
    @Resource
    private UserAddressRepository userAddressRepository;
    @Resource
    private BaseAssemblerFactory baseAssemblerFactory;
    @Resource
    private AddAccountEventPublisher addAccountEventPublisher;

    @Transactional
    @Override
    public RespBody<User> register(RegisterDTO registerDTO) {
        RegisterAssembler registerAssembler = new RegisterAssembler(baseAssemblerFactory);
        User user = registerAssembler.toEntity(registerDTO);
        userRepository.save(user);
        UserInfo userInfo = user.getUserInfo();
        userInfo.setUserId(user.getId());
        userInfoRepository.save(userInfo);
        UserAddress userAddress = userInfo.getAddress();
        userAddress.setUserInfoId(userInfo.getId());
        userAddressRepository.save(userAddress);
        addAccountEventPublisher.publishAddAccountEvent(user.getId(), user.getName(), registerDTO.getClientId());
        return RespBody.ok(user);
    }
}

